
#include<QtGui/QLabel>
#include<QtGui/QTableWidget>
#include<QtGui/QTableView>
#include<QtGui/QFileDialog>
#include<QtCore/QtAlgorithms>
#include<QtGui/QSystemTrayIcon>
#include<QtCore/QSettings>
#include<QtGui/QMenu>
#include<QtGui/QCloseEvent>
#include<QtGui/QMenuBar>
#include<QtGui/QMessageBox>
#include<QtGui/QToolBar>
#include<QtGui/QStatusBar>
#include<QtGui/QLCDNumber>
#include<QtCore/QTime>
#include<QTextCodec>
#include"mainwindow.h"
#include"titleselectdialog.h"
#include"musictag.h"
#include"selectedrangecmp.h"
#include"decoder.h"
#include"tageditdialog.h"
#include"searchmp3dialog.h"
#include"showmusicinfo.h"
#include"aboutdialog.h"

MainWindow::MainWindow()
{
    MainWindowTitle="SLZmusic";
    MainWindow::setWindowTitle(MainWindowTitle);
    MainWindow::setWindowIcon(QIcon(":/Icons/desktop.png"));
    MainWindow::height();
    createActions();
    createList();
    createDecoder();
    createSeekSlider();
    createLCD();
    createVolumeSlider();
    connect(Decoder->mediaObject,SIGNAL(tick(qint64)),this,SLOT(tickSlot(qint64)));
    createMenus();
    createStatusBar();
    createContextMenu();
    createTrayIcon();
    MainWindow::setCentralWidget(MusicTable);
    readSetting();
    createToolBars();  //must be later than reading setting
    connect(this,SIGNAL(CurrentSongChanged()),this,SLOT(play()));
    connect(this,SIGNAL(MusicTableChanged()),this,SLOT(refreshHashSlot()));
    MusicTable->setSortingEnabled(true);
    update();
}

void MainWindow::createDecoder()
{
    Decoder = new decoder();
    this->CurrentSongNum = -1;
    this->setPlayStateSlot(false);
    Decoder->loadFile(this->getCurrentSongPath());
    connect(Decoder,SIGNAL(AboutToFinish()),this,SLOT(playNextSong()));
}

void MainWindow::createTrayIcon()
{
    TrayIcon = new QSystemTrayIcon(this);
    TrayIcon->setIcon(QIcon(":/Icons/desktop.png"));
    TrayIcon->setVisible(QSystemTrayIcon::isSystemTrayAvailable());
    TrayIconMenu = new QMenu(this);
    TrayIconMenu->addAction(PlayAction);
    TrayIconMenu->addSeparator();
    TrayIconMenu->addAction(PreviousSongAction);
    TrayIconMenu->addAction(NextSongAction);
    TrayIconMenu->addSeparator();
    TrayIconMenu->addAction(ShowMainWindowAction);
    TrayIconMenu->addAction(ExitAction);
    TrayIcon->setContextMenu(TrayIconMenu);
    connect(this,SIGNAL(CurrentSongChanged()),this,SLOT(showSongMessage()));
    connect(TrayIcon,SIGNAL(messageClicked()),this,SLOT(showMaximized()));
    TrayIcon->show();
}

void MainWindow::removeFromListSlot()
{
    MusicTable->setSortingEnabled(false);
    QList<QTableWidgetSelectionRange> temp = MusicTable->selectedRanges();
    qSort(temp.begin(),temp.end(),SelectedRangeCmp);

    for(int i = 0 ; i <temp.size() ; i++){
        for(int j=temp[i].bottomRow() ; j>=temp[i].topRow() ; --j)
        {
            MusicTable->removeRow(j);
        }
    }
    emit MusicTableChanged();
    MusicTable->update();
    MusicTable->setSortingEnabled(true);
}

void MainWindow::createContextMenu()
{
    MusicTable->setContextMenuPolicy(Qt::ActionsContextMenu);
    MusicTable->addAction(RemoveFromListAction);
    //MusicTable->addAction(MoveToTrashAction);
    MusicTable->addAction(EditTagAction);
    //SelectEncodingMenu = new QMenu(tr("select encoding"),this);
    MusicTable->addAction(SetEncodingGB18030Action);
    MusicTable->addAction(SetEncodingUTF8Action);
    //MusicTable->addAction(SetEncodingGBKAction);
    MusicTable->addAction(SetEncodingLatin1Action);
    MusicTable->addAction(SetEncodingBIG5Action);

}

void MainWindow::closeEvent(QCloseEvent *event)
{
    saveConfigSlot();
    event->accept();
}

void MainWindow::readSetting()
{
    QSettings setting("SLZ Software","SLZmusic");

    restoreGeometry(setting.value("geometry").toByteArray());
    titleChangedSlot(setting.value("title").toStringList());
    MusicTable->setRowCount(setting.value("titleRow").toInt());
    if(setting.value("columnWidth0").toInt() != 0){
        MusicTable->setColumnWidth(0,setting.value("columnWidth0").toInt());
        MusicTable->setColumnWidth(1,setting.value("columnWidth1").toInt());
        MusicTable->setColumnWidth(2,setting.value("columnWidth2").toInt());
        MusicTable->setColumnWidth(3,setting.value("columnWidth3").toInt());
        MusicTable->setColumnWidth(4,setting.value("columnWidth4").toInt());
        MusicTable->setColumnWidth(5,setting.value("columnWidth5").toInt());
        MusicTable->setColumnWidth(6,setting.value("columnWidth6").toInt());
    }
    this->setPlayStateSlot(setting.value("random").toBool());
    this->RandomPlayAction->setChecked(setting.value("random").toBool());
    this->Decoder->audioOutput->setVolume(setting.value("volume").toReal());
    QFile file("config.dat");
    if(!file.open(QIODevice::ReadOnly)){
        //QMessageBox::warning(this,tr("Wrong"),tr("Can't open config file"));
        MusicTable->setRowCount(0);
        return;
    }

    QDataStream in(&file);
    in.setVersion(QDataStream::Qt_4_6);
    int i = 0;
    int j = 0;
    while(!file.atEnd()){
        in>>i>>j;
        QTableWidgetItem * TWI = new QTableWidgetItem();
        TWI->read(in);
        MusicTable->setItem(i,j,TWI);
    }
    emit MusicTableChanged();
}

void MainWindow::saveConfigSlot()
{
    QSettings setting("SLZ Software","SLZmusic");
    setting.setValue("geometry",saveGeometry());
    setting.setValue("titleRow",MusicTable->rowCount());
    setting.setValue("random",this->getPlayState());
    setting.setValue("volume",Decoder->audioOutput->volume());
    setting.setValue("columnWidth0",MusicTable->columnWidth(0));
    setting.setValue("columnWidth1",MusicTable->columnWidth(1));
    setting.setValue("columnWidth2",MusicTable->columnWidth(2));
    setting.setValue("columnWidth3",MusicTable->columnWidth(3));
    setting.setValue("columnWidth4",MusicTable->columnWidth(4));
    setting.setValue("columnWidth5",MusicTable->columnWidth(5));
    setting.setValue("columnWidth6",MusicTable->columnWidth(6));
    QFile file("config.dat");
    if(!file.open(QIODevice::WriteOnly)){
        QMessageBox::warning(this,tr("Wrong"),tr("Can't open config file"));
        return;
    }

    QDataStream out(&file);
    out.setVersion(QDataStream::Qt_4_6);
    for(int i=0;i<MusicTable->rowCount();i++)
        for(int j=0;j<MusicTable->columnCount();j++){
        if(MusicTable->item(i,j)){
            out<<i<<j;
            MusicTable->item(i,j)->write(out);
        }
    }

}

void MainWindow::titleChangedSlot(QStringList Tags)
{
    if(Tags.empty()){
        QStringList temp;
        temp<<tr("Name")<<tr("Artist")<<tr("Album")<<tr("Genre")<<tr("Time")<<tr("Year");
        titleChangedSlot(temp);
        for(int i=0;i<7;i++){
            MusicTable->setColumnWidth(i,100);
        }
        return;
    }
    for(int i=0 ; i<7 ;i++)
        MusicTable->setColumnHidden(i,true);
    for(int i=0 ; i<Tags.size() ; i++){
        if(Tags.at(i) == tr("Name"))
            MusicTable->setColumnHidden(MainWindow::TITLE,false);
        else if(Tags.at(i) == tr("Album"))
            MusicTable->setColumnHidden(MainWindow::ALBUM,false);
        else if(Tags.at(i) == tr("Artist"))
            MusicTable->setColumnHidden(MainWindow::ARTIST,false);
        else if(Tags.at(i) == tr("Genre"))
            MusicTable->setColumnHidden(MainWindow::GENRE,false);
        else if(Tags.at(i) == tr("Time"))
            MusicTable->setColumnHidden(MainWindow::TIME,false);
        else if(Tags.at(i) == tr("Year"))
            MusicTable->setColumnHidden(MainWindow::YEAR,false);
        else if(Tags.at(i) == tr("Location"))
            MusicTable->setColumnHidden(MainWindow::LOCATION,false);
    }
    update();
    QSettings setting("SLZ Software","SLZmusic");
    setting.setValue("title",Tags);
}

void MainWindow::importDocumentSlot()
{
    MusicTable->setSortingEnabled(false);
    QString DirName;
    DirName = QFileDialog::getExistingDirectory(this,"select directroy to import","/home",
                                                QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);

    QStringList Filter;
    Filter<<"*.mp3";

    QDir Dir;
    Dir.setPath(DirName);

    QFileInfoList FileInfo;
    FileInfo = Dir.entryInfoList(Filter,QDir::Files);
    if(!FileInfo.isEmpty()){
        for(int i = 0;i< FileInfo.size();i++){

            if(!ListHash.contains(qHash(FileInfo.at(i).absoluteFilePath()))){
                MusicTag MT(FileInfo.at(i).absoluteFilePath(),true);
                MusicTable->setRowCount(MusicTable->rowCount()+1);

                QTableWidgetItem * iName = new QTableWidgetItem();
                if(!MT.title().isEmpty())
                    iName->setData(Qt::DisplayRole,MT.title());
                else
                    iName->setData(Qt::DisplayRole,FileInfo.at(i).baseName());
                MusicTable->setItem(MusicTable->rowCount()-1,MainWindow::TITLE,iName);

                QTableWidgetItem *iArtist = new QTableWidgetItem();
                iArtist->setData(Qt::DisplayRole,MT.artist());
                MusicTable->setItem(MusicTable->rowCount()-1,MainWindow::ARTIST,iArtist);

                QTableWidgetItem *iAlbum = new QTableWidgetItem();
                iAlbum->setData(Qt::DisplayRole,MT.album());
                MusicTable->setItem(MusicTable->rowCount()-1,MainWindow::ALBUM,iAlbum);

                QTableWidgetItem *iGenre = new QTableWidgetItem();
                iGenre->setData(Qt::DisplayRole,MT.genre());
                MusicTable->setItem(MusicTable->rowCount()-1,MainWindow::GENRE,iGenre);

                QTableWidgetItem *iTime = new QTableWidgetItem();
                iTime->setData(Qt::DisplayRole,MT.lengthStr());
                MusicTable->setItem(MusicTable->rowCount()-1,MainWindow::TIME,iTime);

                QTableWidgetItem *iYear = new QTableWidgetItem();
                iYear->setData(Qt::DisplayRole,MT.year());
                MusicTable->setItem(MusicTable->rowCount()-1,MainWindow::YEAR,iYear);

                QTableWidgetItem *iLocation = new QTableWidgetItem();
                iLocation->setData(Qt::DisplayRole,FileInfo.at(i).absoluteFilePath());
                MusicTable->setItem(MusicTable->rowCount()-1,MainWindow::LOCATION,iLocation);

                emit MusicTableChanged();
                update();
            }
        }
    }
    MusicTable->setSortingEnabled(true);
}



void MainWindow::importFileSlot()
{
    MusicTable->setSortingEnabled(false);
    QStringList FileName;
    FileName = QFileDialog::getOpenFileNames(this,"select music files to import","/home","Mp3 (*.mp3)");
    if(!FileName.isEmpty()){
        for(int i = 0;i< FileName.size();i++){

            if(!ListHash.contains(qHash(FileName.at(i)))){
                MusicTag MT(FileName.at(i),true);
                MusicTable->setRowCount(MusicTable->rowCount()+1);

                QTableWidgetItem * iName = new QTableWidgetItem();
                if(!MT.title().isEmpty())
                    iName->setData(Qt::DisplayRole,MT.title());
                else
                    iName->setData(Qt::DisplayRole,QFileInfo(FileName.at(i)).baseName());
                MusicTable->setItem(MusicTable->rowCount()-1,0,iName);

                QTableWidgetItem *iArtist = new QTableWidgetItem();
                iArtist->setData(Qt::DisplayRole,MT.artist());
                MusicTable->setItem(MusicTable->rowCount()-1,1,iArtist);

                QTableWidgetItem *iAlbum = new QTableWidgetItem();
                iAlbum->setData(Qt::DisplayRole,MT.album());
                MusicTable->setItem(MusicTable->rowCount()-1,2,iAlbum);

                QTableWidgetItem *iGenre = new QTableWidgetItem();
                iGenre->setData(Qt::DisplayRole,MT.genre());
                MusicTable->setItem(MusicTable->rowCount()-1,3,iGenre);

                QTableWidgetItem *iTime = new QTableWidgetItem();
                iTime->setData(Qt::DisplayRole,MT.lengthStr());
                MusicTable->setItem(MusicTable->rowCount()-1,4,iTime);

                QTableWidgetItem *iYear = new QTableWidgetItem();
                iYear->setData(Qt::DisplayRole,MT.year());
                MusicTable->setItem(MusicTable->rowCount()-1,5,iYear);

                QTableWidgetItem *iLocation = new QTableWidgetItem();
                iLocation->setData(Qt::DisplayRole,FileName.at(i));
                MusicTable->setItem(MusicTable->rowCount()-1,6,iLocation);

                emit MusicTableChanged();
                update();
            }
        }
    }
    MusicTable->setSortingEnabled(true);
}

void MainWindow::selectTitleSlot()
{
    TitleSelectDialog *TSD = new TitleSelectDialog(this);
    connect(TSD,SIGNAL(titleChanged(QStringList)),this,SLOT(titleChangedSlot(QStringList)));
    TSD->show();
}

void MainWindow::toolbarVisibleSlot(bool b)
{
    b == true?PlayToolBar->setVisible(true):PlayToolBar->setVisible(false);
}

void MainWindow::createLayout()
{
    Layout = new QVBoxLayout(CentraWidget);
    Layout->addWidget(MusicTable);
}

void MainWindow::createList()
{

    MusicTable = new QTableWidget(0,7,this);
    MusicTable->setSelectionMode(QAbstractItemView::ExtendedSelection);
    MusicTable->setSelectionBehavior(QAbstractItemView::SelectRows);
    MusicTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
    MusicTable->setHorizontalHeaderLabels(QStringList()<<tr("Name")<<tr("Artist")<<tr("Album")
                                          <<tr("Genre")<<tr("Time")<<tr("Year")<<tr("Disk Loaction"));
    MusicTable->setSortingEnabled(false);
    connect(MusicTable,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(setCurrentSongNumSlot(QModelIndex)));
    connect(this,SIGNAL(CurrentSongChanged()),this,SLOT(setPlayingSongSelectedSlot()));
}

void MainWindow::createMenus()
{
    FileMenu = menuBar()->addMenu(tr("File"));  //menuBar()是qt自带函数
    FileMenu->addAction(ImportFileAction);
    FileMenu->addAction(ImportDocumentAction);
    FileMenu->addSeparator();
    FileMenu->addSeparator();
    FileMenu->addAction(ExitAction);

    PlayMenu = menuBar()->addMenu(tr("Play"));
    PlayMenu->addAction(PlayAction);
    PlayMenu->addAction(NextSongAction);
    PlayMenu->addAction(PreviousSongAction);
    //PlayMenu->setIcon(QIcon(":/Icons/play.png"));  //菜单也可有图标

    ViewMenu = menuBar()->addMenu(tr("View"));
    ViewMenu->addAction(ShowToolbarAction);
    ViewMenu->addAction(SelectTitleAction);
    //ViewMenu->addAction(SimpleMode);

    HelpMenu = menuBar()->addMenu(tr("Help"));
    HelpMenu->addAction(AboutAction);
}

void MainWindow::createActions()
{
    ImportFileAction = new QAction(tr("&Import File"),this);
    ImportFileAction->setIconVisibleInMenu(true);
    ImportFileAction->setStatusTip(tr("import a music file into the list"));
    ImportFileAction->setCheckable(false);
    connect(ImportFileAction,SIGNAL(triggered()),this,SLOT(importFileSlot()));

    ImportDocumentAction = new QAction(tr("Import Document"),this);
    ImportDocumentAction->setIconVisibleInMenu(true);
    ImportDocumentAction->setStatusTip(tr("select a document containing music and import all the music into the list"));
    connect(ImportDocumentAction,SIGNAL(triggered()),this,SLOT(importDocumentSlot()));

    ExitAction = new QAction(tr("Exit"),this);
    ExitAction->setIconVisibleInMenu(true);
    ExitAction->setStatusTip(tr("exit SLZmusic"));
    connect(ExitAction,SIGNAL(triggered()),this,SLOT(close()));

    ShowMainWindowAction = new QAction(tr("show SLZmusic"),this);
    connect(ShowMainWindowAction,SIGNAL(triggered()),this,SLOT(showMaximized()));

    PlayAction = new QAction(tr("Play"),this);
    PlayAction->setIconVisibleInMenu(true);
    PlayAction->setCheckable(true);
    PlayAction->setChecked(false);
    PlayAction->setIcon(QIcon(":/Icons/play.png"));
    connect(PlayAction,SIGNAL(triggered(bool)),this,SLOT(playControlSlot(bool)));
    connect(PlayAction,SIGNAL(triggered(bool)),PlayAction,SLOT(setChecked(bool)));
    connect(this,SIGNAL(CurrentSongChanged()),this,SLOT(setPlayActionToggled()));

    NextSongAction =new QAction(tr("Next Song"),this);
    NextSongAction->setIconVisibleInMenu(true);
    NextSongAction->setIcon(QIcon(":/Icons/forward.png"));
    connect(NextSongAction,SIGNAL(triggered()),this,SLOT(playNextSong()));

    PreviousSongAction = new QAction(tr("Previous Song"),this);
    PreviousSongAction->setIconVisibleInMenu(true);
    PreviousSongAction->setIcon(QIcon(":/Icons/back.png"));
    connect(PreviousSongAction,SIGNAL(triggered()),this,SLOT(playPreviousSong()));

    RandomPlayAction = new QAction(tr("Random play"),this);
    RandomPlayAction->setIconVisibleInMenu(true);
    RandomPlayAction->setIcon(QIcon(":/Icons/random.png"));
    RandomPlayAction->setCheckable(true);
    RandomPlayAction->setChecked(false);
    connect(RandomPlayAction,SIGNAL(triggered(bool)),this,SLOT(setPlayStateSlot(bool)));

    ShowToolbarAction = new QAction(tr("Show Toolbar"),this);
    ShowToolbarAction->setCheckable(true);
    ShowToolbarAction->setChecked(true);

    connect(ShowToolbarAction,SIGNAL(triggered(bool)),this,SLOT(toolbarVisibleSlot(bool)) );

    SelectTitleAction = new QAction(tr("Titles"),this);
    SelectTitleAction->setStatusTip(tr("select the titles of the song list table"));

    connect(SelectTitleAction,SIGNAL(triggered()),this,SLOT(selectTitleSlot()));

    AboutAction = new QAction(tr("About"),this);
    AboutAction->setIconVisibleInMenu(true);
    AboutAction->setStatusTip(tr("show infomations about SLZmusic"));
    connect(AboutAction,SIGNAL(triggered()),this,SLOT(aboutSlot()));

    RemoveFromListAction = new QAction(tr("remove from list"),this);
    RemoveFromListAction->setStatusTip(tr("remove this song from list but not delete it from hard disk"));
    RemoveFromListAction->setShortcut(Qt::Key_Delete);
    connect(RemoveFromListAction,SIGNAL(triggered()),this,SLOT(removeFromListSlot()));

    SetEncodingGB18030Action = new QAction(tr("GB18030"),this);
    connect(SetEncodingGB18030Action,SIGNAL(triggered()),this,SLOT(setEncodingGB18030()));

    SetEncodingGBKAction = new QAction(tr("GBK"),this);
    connect(SetEncodingGBKAction,SIGNAL(triggered()),this,SLOT(setEncodingGBK()));

    SetEncodingBIG5Action = new QAction(tr("BIG5"),this);
    connect(SetEncodingBIG5Action,SIGNAL(triggered()),this,SLOT(setEncodingBIG5()));

    SetEncodingLatin1Action = new QAction(tr("Latin1"),this);
    connect(SetEncodingLatin1Action,SIGNAL(triggered()),this,SLOT(setEncodingLatin1()));

    SetEncodingUTF8Action = new QAction(tr("UTF8"),this);
    connect(SetEncodingUTF8Action,SIGNAL(triggered()),this,SLOT(setEncodingUTF8()));

    connect(this,SIGNAL(Encoding(QString)),this,SLOT(setEncodingSlot(QString)));

    EditTagAction = new QAction(tr("edit property"),this);
    connect(EditTagAction,SIGNAL(triggered()),this,SLOT(editTagSlot()));

    MoveToTrashAction = new QAction(tr("move to trash"),this);
    connect(MoveToTrashAction,SIGNAL(triggered()),this,SLOT(moveToTrashSlot()));

}

void MainWindow::createToolBars()
{
    PlayToolBar = addToolBar(tr("Play"));  //addToolBar()是自带函数
    PlayToolBar->addAction(PlayAction);
    PlayToolBar->addAction(PreviousSongAction);
    PlayToolBar->addAction(NextSongAction);  //toolbar也可以->addSeperator()
    PlayToolBar->addAction(RandomPlayAction);
    PlayToolBar->addWidget(MainSeekSlider);
    PlayToolBar->addWidget(LCD);
    PlayToolBar->addWidget(MainVolumeSlider);
    this->addToolBarBreak();

    MusicInfoToolBar = addToolBar(tr("MusicInfo"));
    MusicInfo = new ShowMusicInfo(this);
    MusicInfoToolBar->addWidget(MusicInfo);
    connect(this,SIGNAL(CurrentSongChanged()),this,SLOT(refreshMusicInfoSlot()));

    SearchToolBar = addToolBar(tr("search"));
    SearchToolBar->setMinimumWidth(200);
    SMD = new SearchMp3Dialog(this);
    SMD->setTable(MusicTable);
    SearchToolBar->addWidget(SMD);
}

void MainWindow::createStatusBar()
{
    ConclusionLabel = new QLabel();
    ConclusionLabel->setAlignment(Qt::AlignLeft);

    statusBar()->addWidget(ConclusionLabel);

    //updateStatusBar();   //StatusBar比较特殊
}

QString MainWindow::getCurrentSongPath()
{
    if(this->CurrentSongNum<0)
        return QString();
    return this->MusicTable->item(CurrentSongNum,LOCATION)->data(Qt::DisplayRole).toString();
}

MainWindow::PlayState MainWindow::getPlayState()
{
    return State;
}

void MainWindow::playNextSong()
{
    if(!SMD->isSearching()){
        if(MusicTable->rowCount() == 0)return;   //can return out of the function?
        switch(getPlayState())
        {
        case RANDOM:
            qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
            CurrentSongNum = qrand()%this->MusicTable->rowCount();
            break;
        case SEQUENCY:
            CurrentSongNum = CurrentSongNum == this->MusicTable->rowCount()-1?0:CurrentSongNum+1;
            break;
        }
        MusicTable->scrollToItem(MusicTable->item(CurrentSongNum,MainWindow::TITLE));
    }
    else
    {
        if(SMD->getRowList().size() == 0)return;
        switch(getPlayState())
        {
        case MainWindow::RANDOM:
            qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
            CurrentSongNum = SMD->getRowList().at(qrand()%SMD->getRowList().size());
            break;
        case MainWindow::SEQUENCY:
            if(SMD->getRowList().contains(CurrentSongNum))
                CurrentSongNum = SMD->getRowList().indexOf(CurrentSongNum) == SMD->getRowList().size()-1?SMD->getRowList().at(0):SMD->getRowList().at(SMD->getRowList().indexOf(CurrentSongNum)+1);
            else
                CurrentSongNum = SMD->getRowList().at(0);
            break;
        }
    }
    if(!QFile::exists(getCurrentSongPath())){
        MusicTable->setSortingEnabled(false);
        MusicTable->removeRow(this->CurrentSongNum);
        emit MusicTableChanged();
        MusicTable->update();
        MusicTable->setSortingEnabled(true);
        this->playNextSong();
    }
    else{
        Decoder->loadFile(getCurrentSongPath());
        emit CurrentSongChanged();
    }
}

void MainWindow::playPreviousSong()
{
    if(!SMD->isSearching()){
        if(MusicTable->rowCount() == 0)return;
        switch(getPlayState())
        {
        case RANDOM:
            qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
            CurrentSongNum = qrand()%this->MusicTable->rowCount();
            break;
        case SEQUENCY:
            CurrentSongNum = CurrentSongNum == 0?this->MusicTable->rowCount()-1:CurrentSongNum-1;
            break;
        }
        MusicTable->scrollToItem(MusicTable->item(CurrentSongNum,MainWindow::TITLE));
    }
    else{
        if(SMD->getRowList().size() == 0)return;
        switch(getPlayState())
        {
        case MainWindow::RANDOM:
            qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
            CurrentSongNum = SMD->getRowList().at(qrand()%SMD->getRowList().size());
            break;
        case MainWindow::SEQUENCY:
            if(SMD->getRowList().contains(CurrentSongNum))
                CurrentSongNum = SMD->getRowList().indexOf(CurrentSongNum) == 0?*(SMD->getRowList().end()-1):SMD->getRowList().at(SMD->getRowList().indexOf(CurrentSongNum)-1);
            else
                CurrentSongNum = SMD->getRowList().at(0);
            break;
        }

    }
    if(!QFile::exists(getCurrentSongPath())){
        MusicTable->setSortingEnabled(false);
        MusicTable->removeRow(this->CurrentSongNum);
        emit MusicTableChanged();
        MusicTable->update();
        MusicTable->setSortingEnabled(true);
        this->playPreviousSong();
    }
    else{
        Decoder->loadFile(getCurrentSongPath());
        emit CurrentSongChanged();
    }
}

void MainWindow::pause()
{
    Decoder->pause();
}

void MainWindow::setPlayStateSlot(bool b)
{
    b == true?this->State = RANDOM:this->State = SEQUENCY;
}

void MainWindow::play()
{
    Decoder->play();
}

void MainWindow::setCurrentSongNumSlot(QModelIndex a)
{

    this->CurrentSongNum = a.row();

    if(!QFile::exists(getCurrentSongPath())){
        MusicTable->setSortingEnabled(false);
        MusicTable->removeRow(this->CurrentSongNum);
        emit MusicTableChanged();
        MusicTable->update();
        MusicTable->setSortingEnabled(true);
    }
    else{
        Decoder->loadFile(this->getCurrentSongPath());
        emit this->CurrentSongChanged();
    }
}

void MainWindow::playControlSlot(bool b)
{
    if(!SMD->isSearching()){
        if(MusicTable->rowCount() == 0)return;
        if(this->CurrentSongNum < 0){
            if(MusicTable->rowCount() != 0)
            {
                bool hasValidSong = false;
                while(hasValidSong == false)
                {
                    if(this->getPlayState() == this->RANDOM)
                        this->CurrentSongNum = rand()%this->MusicTable->rowCount();
                    else this->CurrentSongNum = 0;
                    if(QFile::exists(this->getCurrentSongPath()))
                        hasValidSong = true;
                    else{
                        MusicTable->setSortingEnabled(false);
                        MusicTable->removeRow(this->CurrentSongNum);
                        emit MusicTableChanged();
                        MusicTable->update();
                        MusicTable->setSortingEnabled(true);
                        if(MusicTable->rowCount() == 0){
                            this->CurrentSongNum = -1;
                            return;
                        }
                    }
                }
                Decoder->loadFile(this->getCurrentSongPath());
            }
            else
                this->CurrentSongNum = -1;
        }
    }
    else{
        if(CurrentSongNum < 0){
            if(SMD->getRowList().size() == 0)return;
            bool hasValidSong = false;
            while(hasValidSong == false){
                switch(getPlayState())
                {
                case MainWindow::RANDOM:
                    qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
                    CurrentSongNum = SMD->getRowList().at(qrand()%SMD->getRowList().size());
                    break;
                case MainWindow::SEQUENCY:
                    if(SMD->getRowList().contains(CurrentSongNum))
                        CurrentSongNum = SMD->getRowList().indexOf(CurrentSongNum) == 0?*(SMD->getRowList().end()-1):SMD->getRowList().at(SMD->getRowList().indexOf(CurrentSongNum)-1);
                    else
                        CurrentSongNum = SMD->getRowList().at(0);
                    break;
                }
                if(QFile::exists(this->getCurrentSongPath()))
                    hasValidSong = true;
                else{
                    MusicTable->setSortingEnabled(false);
                    MusicTable->removeRow(this->CurrentSongNum);
                    emit MusicTableChanged();
                    MusicTable->update();
                    MusicTable->setSortingEnabled(true);
                    if(SMD->getRowList().size() == 0){
                        this->CurrentSongNum = -1;
                        return;
                    }
                }
            }
            Decoder->loadFile(this->getCurrentSongPath());
        }
    }
    if(MusicTable->rowCount() != 0)
        MusicTable->scrollToItem(MusicTable->item(CurrentSongNum,MainWindow::TITLE));
    if(b == true){
        this->play();
        emit this->CurrentSongChanged();
    }
    else this->pause();
}

void MainWindow::setPlayingSongSelectedSlot()
{
    this->MusicTable->setRangeSelected
            (QTableWidgetSelectionRange(0,TITLE,MusicTable->rowCount()-1,LOCATION),false);
    this->MusicTable->setRangeSelected
            (QTableWidgetSelectionRange(CurrentSongNum,TITLE,CurrentSongNum,LOCATION),true);
}

void MainWindow::setPlayActionToggled()
{
    this->PlayAction->setChecked(true);
}

void MainWindow::showSongMessage()
{
    this->TrayIcon->showMessage(tr("SLZmusic"),
                                MusicTable->item(CurrentSongNum,TITLE)->data(Qt::DisplayRole).toString()+"\n"+
                                MusicTable->item(CurrentSongNum,ARTIST)->data(Qt::DisplayRole).toString(),
                                QSystemTrayIcon::NoIcon,
                                5000);
}

void MainWindow::createSeekSlider()
{
    MainSeekSlider = new Phonon::SeekSlider(this);
    MainSeekSlider->setMediaObject(Decoder->mediaObject);
    MainSeekSlider->setVisible(true);
    MainSeekSlider->setTracking(false);
}

void MainWindow::createVolumeSlider()
{
    MainVolumeSlider = new Phonon::VolumeSlider(this);
    MainVolumeSlider->setAudioOutput(Decoder->audioOutput);
    MainVolumeSlider->setVisible(true);
    MainVolumeSlider->setOrientation(Qt::Horizontal);
    MainVolumeSlider->setFixedWidth(200);
}

void MainWindow::createLCD()
{
    LCD = new QLCDNumber(this);
    LCD->display("00:00");
    connect(this,SIGNAL(CurrentSongChanged()),this,SLOT(LCDto0()));
}

void MainWindow::LCDto0()
{
    LCD->display("00:00");
}

void MainWindow::tickSlot(qint64 time)
{
    QTime displayTime(0, (time / 60000) % 60, (time / 1000) % 60);
    LCD->display(displayTime.toString("mm:ss"));
}

void MainWindow::setEncodingGB18030()
{
    emit Encoding("GB18030");
}

void MainWindow::setEncodingGBK()
{
    emit Encoding("GBK");
}

void MainWindow::setEncodingUTF8()
{
    emit Encoding("UTF-8");
}

void MainWindow::setEncodingLatin1()
{
    emit Encoding("Latin-1");
}

void MainWindow::setEncodingBIG5()
{
    emit Encoding("BIG5");
}

void MainWindow::setEncodingSlot(QString encoding)
{
    MusicTable->setSortingEnabled(false);
    QList<QTableWidgetSelectionRange> temp = MusicTable->selectedRanges();

    for(int i = 0 ; i <temp.size() ; ++i)
        for(int j = temp[i].topRow() ; j<=temp[i].bottomRow() ; ++j){

        MusicTag MT(MusicTable->item(j,MainWindow::LOCATION)->data(Qt::DisplayRole).toString(),false);
        MT.setEncoding(encoding);
        MT.readTag();

        MusicTable->item(j,MainWindow::TITLE)->setData(Qt::DisplayRole,MT.title());
        MusicTable->item(j,MainWindow::ALBUM)->setData(Qt::DisplayRole,MT.album());
        MusicTable->item(j,MainWindow::ARTIST)->setData(Qt::DisplayRole,MT.artist());
        MusicTable->item(j,MainWindow::GENRE)->setData(Qt::DisplayRole,MT.genre());
        MusicTable->item(j,MainWindow::TIME)->setData(Qt::DisplayRole,MT.lengthStr());
        MusicTable->item(j,MainWindow::YEAR)->setData(Qt::DisplayRole,MT.year());

        update();
    }
    MusicTable->update();
    MusicTable->setSortingEnabled(true);
}

void MainWindow::editTagSlot()
{
    TagEditDialog *TED = new TagEditDialog(this);
    TED->setMusicTable(this->MusicTable);
    TED->show();
}

void MainWindow::refreshMusicInfoSlot()
{
    this->MusicInfo->getNewSongInfo(MusicTable->item(this->CurrentSongNum,MainWindow::TITLE)->data(Qt::DisplayRole).toString(),
                                    MusicTable->item(this->CurrentSongNum,MainWindow::ARTIST)->data(Qt::DisplayRole).toString(),
                                    MusicTable->item(this->CurrentSongNum,MainWindow::ALBUM)->data(Qt::DisplayRole).toString(),
                                    MusicTable->item(this->CurrentSongNum,MainWindow::GENRE)->data(Qt::DisplayRole).toString());
}

void MainWindow::aboutSlot()
{
    AboutDialog *AD = new AboutDialog(this);
    AD->show();
}

void MainWindow::refreshHashSlot()
{
    ListHash.clear();
    for(int i=0 ; i<MusicTable->rowCount() ; i++){
        ListHash.push_back(qHash(MusicTable->item(i,MainWindow::LOCATION)->data(Qt::DisplayRole).toString()));
    }
}

void MainWindow::playActionControlSlot()
{
}

void MainWindow::moveToTrashSlot()
{
    //duplicate with removeFromListSlot
    MusicTable->setSortingEnabled(false);
    QList<QTableWidgetSelectionRange> temp = MusicTable->selectedRanges();
    qSort(temp.begin(),temp.end(),SelectedRangeCmp);

    for(int i = 0 ; i <temp.size() ; i++){
        for(int j=temp[i].bottomRow() ; j>=temp[i].topRow() ; --j)
        {
            QFile::remove(MusicTable->item(j,MainWindow::LOCATION)->data(Qt::DisplayRole).toString());
            MusicTable->removeRow(j);
        }
    }
    emit MusicTableChanged();
    MusicTable->update();
    MusicTable->setSortingEnabled(true);

}
